<!DOCTYPE html>



  


<html class="theme-next pisces use-motion" lang="zh-Hans">
<head>
  <meta charset="UTF-8"/>
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1"/>
<meta name="theme-color" content="#222">









<meta http-equiv="Cache-Control" content="no-transform" />
<meta http-equiv="Cache-Control" content="no-siteapp" />
















  
  
  <link href="/Liang34/lib/fancybox/source/jquery.fancybox.css?v=2.1.5" rel="stylesheet" type="text/css" />







<link href="/Liang34/lib/font-awesome/css/font-awesome.min.css?v=4.6.2" rel="stylesheet" type="text/css" />

<link href="/Liang34/css/main.css?v=5.1.4" rel="stylesheet" type="text/css" />


  <link rel="apple-touch-icon" sizes="180x180" href="/Liang34/images/apple-touch-icon-next.png?v=5.1.4">


  <link rel="icon" type="image/png" sizes="32x32" href="/Liang34/images/favicon-32x32-next.png?v=5.1.4">


  <link rel="icon" type="image/png" sizes="16x16" href="/Liang34/images/favicon-16x16-next.png?v=5.1.4">


  <link rel="mask-icon" href="/Liang34/images/logo.svg?v=5.1.4" color="#222">





  <meta name="keywords" content="Hexo, NexT" />










<meta name="description" content="前端,java">
<meta property="og:type" content="website">
<meta property="og:title" content="liang34">
<meta property="og:url" content="https://liang34.github.io/Liang34/index.html">
<meta property="og:site_name" content="liang34">
<meta property="og:description" content="前端,java">
<meta property="article:author" content="LiangJH">
<meta name="twitter:card" content="summary">



<script type="text/javascript" id="hexo.configurations">
  var NexT = window.NexT || {};
  var CONFIG = {
    root: '/Liang34/',
    scheme: 'Pisces',
    version: '5.1.4',
    sidebar: {"position":"left","display":"post","offset":12,"b2t":false,"scrollpercent":false,"onmobile":false},
    fancybox: true,
    tabs: true,
    motion: {"enable":true,"async":false,"transition":{"post_block":"fadeIn","post_header":"slideDownIn","post_body":"slideDownIn","coll_header":"slideLeftIn","sidebar":"slideUpIn"}},
    duoshuo: {
      userId: '0',
      author: '博主'
    },
    algolia: {
      applicationID: '',
      apiKey: '',
      indexName: '',
      hits: {"per_page":10},
      labels: {"input_placeholder":"Search for Posts","hits_empty":"We didn't find any results for the search: ${query}","hits_stats":"${hits} results found in ${time} ms"}
    }
  };
</script>



  <link rel="canonical" href="https://liang34.github.io/Liang34/"/>





  <title>liang34</title>
  








<meta name="generator" content="Hexo 4.2.0"></head>

<body itemscope itemtype="http://schema.org/WebPage" lang="zh-Hans">

  
  
    
  

  <div class="container sidebar-position-left 
  page-home">
    <div class="headband"></div>

    <header id="header" class="header" itemscope itemtype="http://schema.org/WPHeader">
      <div class="header-inner"><div class="site-brand-wrapper">
  <div class="site-meta ">
    

    <div class="custom-logo-site-title">
      <a href="/Liang34/"  class="brand" rel="start">
        <span class="logo-line-before"><i></i></span>
        <span class="site-title">liang34</span>
        <span class="logo-line-after"><i></i></span>
      </a>
    </div>
      
        <p class="site-subtitle"></p>
      
  </div>

  <div class="site-nav-toggle">
    <button>
      <span class="btn-bar"></span>
      <span class="btn-bar"></span>
      <span class="btn-bar"></span>
    </button>
  </div>
</div>

<nav class="site-nav">
  

  
    <ul id="menu" class="menu">
      
        
        <li class="menu-item menu-item-home">
          <a href="/Liang34/" rel="section">
            
              <i class="menu-item-icon fa fa-fw fa-home"></i> <br />
            
            首页
          </a>
        </li>
      
        
        <li class="menu-item menu-item-tags">
          <a href="/Liang34/tags/" rel="section">
            
              <i class="menu-item-icon fa fa-fw fa-tags"></i> <br />
            
            标签
          </a>
        </li>
      
        
        <li class="menu-item menu-item-categories">
          <a href="/Liang34/categories/" rel="section">
            
              <i class="menu-item-icon fa fa-fw fa-th"></i> <br />
            
            分类
          </a>
        </li>
      
        
        <li class="menu-item menu-item-archives">
          <a href="/Liang34/archives/" rel="section">
            
              <i class="menu-item-icon fa fa-fw fa-archive"></i> <br />
            
            归档
          </a>
        </li>
      

      
    </ul>
  

  
</nav>



 </div>
    </header>

    <main id="main" class="main">
      <div class="main-inner">
        <div class="content-wrap">
          <div id="content" class="content">
            
  <section id="posts" class="posts-expand">
    
      

  

  
  
  

  <article class="post post-type-normal" itemscope itemtype="http://schema.org/Article">
  
  
  
  <div class="post-block">
    <link itemprop="mainEntityOfPage" href="https://liang34.github.io/Liang34/Liang34/2020/03/19/chap2Test/">

    <span hidden itemprop="author" itemscope itemtype="http://schema.org/Person">
      <meta itemprop="name" content="LiangJH">
      <meta itemprop="description" content="">
      <meta itemprop="image" content="/Liang34/images/avatar.jpg">
    </span>

    <span hidden itemprop="publisher" itemscope itemtype="http://schema.org/Organization">
      <meta itemprop="name" content="liang34">
    </span>

    
      <header class="post-header">

        
        
          <h1 class="post-title" itemprop="name headline">
                
                <a class="post-title-link" href="/Liang34/2020/03/19/chap2Test/" itemprop="url">数据结构与算法JavaScript描述[第二章](数组)</a></h1>
        

        <div class="post-meta">
          <span class="post-time">
            
              <span class="post-meta-item-icon">
                <i class="fa fa-calendar-o"></i>
              </span>
              
                <span class="post-meta-item-text">发表于</span>
              
              <time title="创建于" itemprop="dateCreated datePublished" datetime="2020-03-19T22:01:55+08:00">
                2020-03-19
              </time>
            

            

            
          </span>

          
            <span class="post-category" >
            
              <span class="post-meta-divider">|</span>
            
              <span class="post-meta-item-icon">
                <i class="fa fa-folder-o"></i>
              </span>
              
                <span class="post-meta-item-text">分类于</span>
              
              
                <span itemprop="about" itemscope itemtype="http://schema.org/Thing">
                  <a href="/Liang34/categories/%E6%95%B0%E6%8D%AE%E7%BB%93%E6%9E%84%E4%B8%8E%E7%AE%97%E6%B3%95JavaScript%E6%8F%8F%E8%BF%B0/" itemprop="url" rel="index">
                    <span itemprop="name">数据结构与算法JavaScript描述</span>
                  </a>
                </span>

                
                
              
            </span>
          

          
            
          

          
          

          

          

          

        </div>
      </header>
    

    
    
    
    <div class="post-body" itemprop="articleBody">

      
      

      
        
          
            <p>1．创建一个记录学生成绩的对象，提供一个添加成绩的方法，以及一个显示学生平均成绩的方法。</p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br></pre></td><td class="code"><pre><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">Student</span></span>&#123;</span><br><span class="line">    <span class="keyword">constructor</span>(name, grade)&#123;<span class="comment">// constructor是一个构造方法，用来接收参数</span></span><br><span class="line">        <span class="keyword">this</span>.name = name <span class="comment">// this代表的是实例对象</span></span><br><span class="line">        <span class="keyword">this</span>.grade=grade</span><br><span class="line">    &#125;</span><br><span class="line">    addGrade(grade) &#123; <span class="comment">//添加成绩</span></span><br><span class="line">        <span class="keyword">this</span>.grade.push(grade)</span><br><span class="line">    &#125;</span><br><span class="line">    showAverageGrade() &#123;</span><br><span class="line">        <span class="keyword">let</span> temp = <span class="keyword">this</span>.grade.reduce(<span class="function">(<span class="params">p, v</span>) =&gt;</span> p + v)</span><br><span class="line">        <span class="keyword">let</span> averAge = temp/<span class="keyword">this</span>.grade.length</span><br><span class="line">        <span class="built_in">console</span>.log(<span class="keyword">this</span>.name+<span class="string">"平均成绩为："</span>+averAge)</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br><span class="line"><span class="keyword">let</span> stu1 = <span class="keyword">new</span> Student(<span class="string">"lisi"</span>, [<span class="number">92</span>, <span class="number">80</span> ,<span class="number">95</span>])</span><br><span class="line">stu1.addGrade(<span class="number">100</span>)</span><br><span class="line">stu1.showAverageGrade() <span class="comment">// lisi平均成绩为：91.75</span></span><br><span class="line"><span class="keyword">let</span> stu2 = <span class="keyword">new</span> Student(<span class="string">"zhangsan"</span>, [<span class="number">54</span>, <span class="number">86</span> ,<span class="number">20</span>])</span><br><span class="line">stu2.addGrade(<span class="number">100</span>)</span><br><span class="line">stu2.showAverageGrade()  <span class="comment">// zhangsan平均成绩为：65</span></span><br></pre></td></tr></table></figure>
<p>2．将一组单词存储在一个数组中，并按正序和倒序分别显示这些单词。</p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">let</span> arr1 = [<span class="string">"Saber"</span>, <span class="string">"Archer"</span>, <span class="string">"Sakula"</span>, <span class="string">"Fate"</span>, <span class="string">"Caster"</span>]</span><br><span class="line"><span class="built_in">console</span>.log(<span class="string">"正序为："</span>+arr1.sort())</span><br><span class="line"><span class="built_in">console</span>.log(<span class="string">"倒序为："</span>+arr1.reverse())</span><br><span class="line"> <span class="comment">// 或者</span></span><br><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">compare</span> (<span class="params">a, b</span>) </span>&#123;</span><br><span class="line">    <span class="keyword">return</span> b &gt; a</span><br><span class="line">&#125;</span><br><span class="line"><span class="built_in">console</span>.log(<span class="string">"倒序为："</span>+arr1.sort(compare))</span><br></pre></td></tr></table></figure>
<p>3．修改本章前面出现过的weeklyTemps对象，使它可以使用一个二维数组来存储每月的有用数据。增加一些方法用以显示月平均数、具体某一周平均数和所有周的平均数。</p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">//气温</span></span><br><span class="line"><span class="keyword">let</span> Temp = &#123;</span><br><span class="line">    <span class="comment">//温度存储</span></span><br><span class="line">    monthTempStore:[],</span><br><span class="line">    <span class="comment">//周温度存储</span></span><br><span class="line">    weekTempStore:[],</span><br><span class="line">    add:<span class="function"><span class="keyword">function</span> (<span class="params">by,key,temp</span>) </span>&#123;</span><br><span class="line">        <span class="keyword">var</span> strategy = &#123;</span><br><span class="line">            month:<span class="function"><span class="keyword">function</span> (<span class="params">month</span>) </span>&#123;</span><br><span class="line">                Temp.monthTempStore[month] = Temp.monthTempStore[month] || <span class="keyword">new</span> <span class="built_in">Array</span>();</span><br><span class="line">                Temp.monthTempStore[month].push(temp);</span><br><span class="line">            &#125;,</span><br><span class="line">            week:<span class="function"><span class="keyword">function</span> (<span class="params">week</span>) </span>&#123;</span><br><span class="line">                Temp.weekTempStore[week] = Temp.weekTempStore[week] || <span class="keyword">new</span> <span class="built_in">Array</span>();</span><br><span class="line">                Temp.weekTempStore[week].push(temp);</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;;</span><br><span class="line">        strategy[by](key);</span><br><span class="line">    &#125;,</span><br><span class="line">    average:<span class="function"><span class="keyword">function</span> (<span class="params">by,key</span>) </span>&#123;</span><br><span class="line">        <span class="keyword">var</span> sum = <span class="number">0</span>;</span><br><span class="line">        <span class="keyword">var</span> i = <span class="number">0</span>;</span><br><span class="line">        <span class="keyword">var</span> strategy = &#123;</span><br><span class="line">            month:<span class="function"><span class="keyword">function</span> (<span class="params"></span>) </span>&#123;</span><br><span class="line">                <span class="keyword">for</span>(;i &lt; Temp.monthTempStore[key].length; i++)&#123;</span><br><span class="line">                    sum += Temp.monthTempStore[key][i];</span><br><span class="line">                &#125;</span><br><span class="line">                <span class="keyword">return</span> sum / i;</span><br><span class="line">            &#125;,</span><br><span class="line">            week:<span class="function"><span class="keyword">function</span> (<span class="params"></span>) </span>&#123;</span><br><span class="line">                <span class="keyword">for</span>(;i &lt; Temp.weekTempStore[key].length; i++)&#123;</span><br><span class="line">                    sum += Temp.weekTempStore[key][i];</span><br><span class="line">                &#125;</span><br><span class="line">                <span class="keyword">return</span> sum / i;</span><br><span class="line">            &#125;,</span><br><span class="line">            allWeek:<span class="function"><span class="keyword">function</span> (<span class="params"></span>) </span>&#123;</span><br><span class="line">                <span class="keyword">var</span> index = <span class="number">0</span>;</span><br><span class="line">                <span class="keyword">for</span>(;i &lt; Temp.weekTempStore.length; i++)&#123;</span><br><span class="line">                    <span class="keyword">if</span>(Temp.weekTempStore[i])&#123;</span><br><span class="line">                        <span class="keyword">for</span>(<span class="keyword">var</span> j = <span class="number">0</span> ; j &lt; Temp.weekTempStore[i].length; j++)&#123;</span><br><span class="line">                            sum += Temp.weekTempStore[i][j];</span><br><span class="line">                            ++index;</span><br><span class="line">                        &#125;</span><br><span class="line">                    &#125;</span><br><span class="line">                &#125;</span><br><span class="line">                <span class="keyword">return</span> sum / index;</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;;</span><br><span class="line">        <span class="keyword">return</span> strategy[by]();</span><br><span class="line">    &#125;</span><br><span class="line">&#125;;</span><br><span class="line"><span class="comment">//   存储每个月有用数据</span></span><br><span class="line">Temp.add(<span class="string">'month'</span>,<span class="number">1</span>,<span class="number">20</span>);</span><br><span class="line">Temp.add(<span class="string">'month'</span>,<span class="number">1</span>,<span class="number">30</span>);</span><br><span class="line">Temp.add(<span class="string">'month'</span>,<span class="number">1</span>,<span class="number">30</span>);</span><br><span class="line"><span class="comment">//1月份平均温度 =&gt; 月平均数</span></span><br><span class="line"><span class="built_in">console</span>.log(Temp.average(<span class="string">'month'</span>,<span class="number">1</span>));</span><br><span class="line">Temp.add(<span class="string">'week'</span>,<span class="number">1</span>,<span class="number">30</span>);</span><br><span class="line">Temp.add(<span class="string">'week'</span>,<span class="number">1</span>,<span class="number">40</span>);</span><br><span class="line">Temp.add(<span class="string">'week'</span>,<span class="number">2</span>,<span class="number">40</span>);</span><br><span class="line"><span class="comment">//第1周温度平均数 =&gt; 某一周平均数</span></span><br><span class="line"><span class="built_in">console</span>.log(Temp.average(<span class="string">'week'</span>,<span class="number">1</span>));</span><br><span class="line"><span class="comment">//所有周平均数</span></span><br><span class="line"><span class="built_in">console</span>.log(Temp.average(<span class="string">'allWeek'</span>));</span><br></pre></td></tr></table></figure>
<p>4．创建这样一个对象，它将字母存储在一个数组中，并且用一个方法可以将字母连在一起，显示成一个单词。</p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">let</span> obj = &#123;</span><br><span class="line">    alphabet:[<span class="string">"s"</span>, <span class="string">"a"</span>, <span class="string">"k"</span>,<span class="string">"u"</span>, <span class="string">"l"</span>, <span class="string">"a"</span>],</span><br><span class="line">    joinAlpha: <span class="function"><span class="keyword">function</span>(<span class="params"></span>)</span>&#123;</span><br><span class="line">        <span class="keyword">return</span> <span class="keyword">this</span>.alphabet.join(<span class="string">""</span>)</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br><span class="line"><span class="built_in">console</span>.log(obj.joinAlpha())</span><br></pre></td></tr></table></figure>
          
        
      
    </div>
    
    
    

    

    

    

    <footer class="post-footer">
      

      

      

      
      
        <div class="post-eof"></div>
      
    </footer>
  </div>
  
  
  
  </article>


    
      

  

  
  
  

  <article class="post post-type-normal" itemscope itemtype="http://schema.org/Article">
  
  
  
  <div class="post-block">
    <link itemprop="mainEntityOfPage" href="https://liang34.github.io/Liang34/Liang34/2020/03/19/ArrayTraverse/">

    <span hidden itemprop="author" itemscope itemtype="http://schema.org/Person">
      <meta itemprop="name" content="LiangJH">
      <meta itemprop="description" content="">
      <meta itemprop="image" content="/Liang34/images/avatar.jpg">
    </span>

    <span hidden itemprop="publisher" itemscope itemtype="http://schema.org/Organization">
      <meta itemprop="name" content="liang34">
    </span>

    
      <header class="post-header">

        
        
          <h1 class="post-title" itemprop="name headline">
                
                <a class="post-title-link" href="/Liang34/2020/03/19/ArrayTraverse/" itemprop="url">ArrayTraverse</a></h1>
        

        <div class="post-meta">
          <span class="post-time">
            
              <span class="post-meta-item-icon">
                <i class="fa fa-calendar-o"></i>
              </span>
              
                <span class="post-meta-item-text">发表于</span>
              
              <time title="创建于" itemprop="dateCreated datePublished" datetime="2020-03-19T11:44:28+08:00">
                2020-03-19
              </time>
            

            

            
          </span>

          

          
            
          

          
          

          

          

          

        </div>
      </header>
    

    
    
    
    <div class="post-body" itemprop="articleBody">

      
      

      
        
          
            
          
        
      
    </div>
    
    
    

    

    

    

    <footer class="post-footer">
      

      

      

      
      
        <div class="post-eof"></div>
      
    </footer>
  </div>
  
  
  
  </article>


    
      

  

  
  
  

  <article class="post post-type-normal" itemscope itemtype="http://schema.org/Article">
  
  
  
  <div class="post-block">
    <link itemprop="mainEntityOfPage" href="https://liang34.github.io/Liang34/Liang34/2020/03/08/Promise/">

    <span hidden itemprop="author" itemscope itemtype="http://schema.org/Person">
      <meta itemprop="name" content="LiangJH">
      <meta itemprop="description" content="">
      <meta itemprop="image" content="/Liang34/images/avatar.jpg">
    </span>

    <span hidden itemprop="publisher" itemscope itemtype="http://schema.org/Organization">
      <meta itemprop="name" content="liang34">
    </span>

    
      <header class="post-header">

        
        
          <h1 class="post-title" itemprop="name headline">
                
                <a class="post-title-link" href="/Liang34/2020/03/08/Promise/" itemprop="url">Promise</a></h1>
        

        <div class="post-meta">
          <span class="post-time">
            
              <span class="post-meta-item-icon">
                <i class="fa fa-calendar-o"></i>
              </span>
              
                <span class="post-meta-item-text">发表于</span>
              
              <time title="创建于" itemprop="dateCreated datePublished" datetime="2020-03-08T21:01:49+08:00">
                2020-03-08
              </time>
            

            

            
          </span>

          
            <span class="post-category" >
            
              <span class="post-meta-divider">|</span>
            
              <span class="post-meta-item-icon">
                <i class="fa fa-folder-o"></i>
              </span>
              
                <span class="post-meta-item-text">分类于</span>
              
              
                <span itemprop="about" itemscope itemtype="http://schema.org/Thing">
                  <a href="/Liang34/categories/JavaScript/" itemprop="url" rel="index">
                    <span itemprop="name">JavaScript</span>
                  </a>
                </span>

                
                
              
            </span>
          

          
            
          

          
          

          

          

          

        </div>
      </header>
    

    
    
    
    <div class="post-body" itemprop="articleBody">

      
      

      
        
          
            <h2 id="Promise"><a href="#Promise" class="headerlink" title="Promise"></a>Promise</h2><h3 id="Can-you-write-a-promise-Yes-I-proimse"><a href="#Can-you-write-a-promise-Yes-I-proimse" class="headerlink" title="Can you write a promise? Yes,I proimse"></a>Can you write a promise? Yes,I proimse</h3><h3 id="What-is-promise"><a href="#What-is-promise" class="headerlink" title="What is promise?"></a>What is promise?</h3><h4 id="在了解promise前，我们先了解一些基本概念："><a href="#在了解promise前，我们先了解一些基本概念：" class="headerlink" title="在了解promise前，我们先了解一些基本概念："></a>在了解promise前，我们先了解一些基本概念：</h4><h3>01.区别函数对象与实例对象</h3>
1.实例对象：new函数产生的对象，称为实例对象，简称对象<br/>
2.函数对象：将函数作为对象使用时，简称函数对
<h3>02.两种回调函数</h3>
1.同步回调：立即执行，不会放入回调队列中，例如：数组遍历相关的回调函数/<b>Promise的excutor函数</b><br/>
2.异步回调：不会立即执行，会放入回调队列中来执行，例如：定时器回调/ajax回调/Promise的成功|失败回调
<h3 style="color:red">03.JS的error处理<h3>
<h4><b>part1.错误的类型</b></h4>
1.Error:所有错误的父类型<br/>
2.ReferError:引用的变量不存在<br/>
3.TypeError:数据类型不正确的错误<br/>
4.RangeError:数据值不在其所允许的范围内，<i>例如var a=new Array(-1)</i><br/>
5.SyntaxError:语法错误<br/>
<h4><b>part2.错误处理</b></h4>
1.捕获错误：try...catch<br/>
2.抛出错误：throw error

<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">handle</span>(<span class="params"></span>) </span>&#123; </span><br><span class="line">    <span class="keyword">if</span> (<span class="built_in">Date</span>.now()%<span class="number">2</span>===<span class="number">0</span>) &#123; </span><br><span class="line">            <span class="keyword">throw</span> <span class="keyword">new</span> <span class="built_in">Error</span>(<span class="string">'时间为偶数, 不能处理逻辑'</span>) </span><br><span class="line">        &#125; </span><br><span class="line">    <span class="keyword">else</span> &#123; </span><br><span class="line">            <span class="built_in">console</span>.log(<span class="string">'时间为奇数, 可以处理逻辑'</span>) </span><br><span class="line">        &#125; </span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">try</span> &#123; </span><br><span class="line">            handle() </span><br><span class="line">        &#125; </span><br><span class="line">    <span class="keyword">catch</span>(error) &#123; <span class="comment">// 捕获错误, 做相应的提示 </span></span><br><span class="line">            alert(<span class="string">'执行出错: '</span> + error.message) </span><br><span class="line">    &#125;</span><br></pre></td></tr></table></figure>

<h4><b>part3.error对象的结构</b></h4>
1.message属性：错误的相关信息<br/>
2.stack属性：函数调用栈记录信息

<hr>
<h1>Promise的理解与使用</h2>

<h3 id="1-抽象表达："><a href="#1-抽象表达：" class="headerlink" title="1.抽象表达："></a>1.抽象表达：</h3><p>Promise是js中进行异步编程的新的解决方案（避免了以往的纯异步嵌套回调）<br/></p>
<h3 id="2-具体表达："><a href="#2-具体表达：" class="headerlink" title="2.具体表达："></a>2.具体表达：</h3><p>(1) 从语法上来说：Promise是一个构造函数<br/><br>(2) 从功能上来说：Promise对象用来封装一个异步操作并可以获取其结果<br/></p>
<h3 id="promise的状态"><a href="#promise的状态" class="headerlink" title="promise的状态"></a>promise的状态</h3><p>1.pending(等待状态)<br/><br>2.resolved(解决状态)<br/><br>3.rejected(拒接状态)<br/><br><b>其中转变只可由:<br/><br>1.pending转为resolved<br/><br>2.pending转为rejected<br/><br>且一个promise只可转变一次<br></b></p>
<h3 id="Promise的基本使用"><a href="#Promise的基本使用" class="headerlink" title="Promise的基本使用"></a>Promise的基本使用</h3><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">//创建Promise对象</span></span><br><span class="line"><span class="keyword">const</span> p=<span class="keyword">new</span> <span class="built_in">Promise</span>(<span class="function">(<span class="params">resolve,reject</span>)=&gt;</span>&#123;</span><br><span class="line">    <span class="comment">//执行异步操作</span></span><br><span class="line">    setTimeout(<span class="function"><span class="params">()</span>=&gt;</span>&#123;</span><br><span class="line">        resolve(<span class="string">"成功了"</span>)<span class="comment">//成功时调用</span></span><br><span class="line">        <span class="comment">//reject("失败了")//失败是调用</span></span><br><span class="line">    &#125;)</span><br><span class="line">&#125;)</span><br><span class="line"><span class="comment">//通过promise的then()指定成功和失败的回调函数</span></span><br><span class="line">p.then(</span><br><span class="line">    value =&gt; <span class="built_in">console</span>.log(value),<span class="comment">//成功了</span></span><br><span class="line">    reason =&gt; <span class="built_in">console</span>.log(reason)<span class="comment">//失败了</span></span><br><span class="line">)</span><br></pre></td></tr></table></figure>
<h3 id="为什么要用Promise"><a href="#为什么要用Promise" class="headerlink" title="为什么要用Promise"></a>为什么要用Promise</h3><h4 id="1-指定回调函数的方式更灵活"><a href="#1-指定回调函数的方式更灵活" class="headerlink" title="1.指定回调函数的方式更灵活"></a>1.指定回调函数的方式更灵活</h4><p>传统必须在启动任务前指定回调<br/><br>而promise先启动异步任务=&gt;返回promise对象=&gt;给promise对象绑定回调函数(甚至可以在异步任务结束后指定)</p>
<h4 id="2-支持链式调用，可以解决回调地狱问题"><a href="#2-支持链式调用，可以解决回调地狱问题" class="headerlink" title="2.支持链式调用，可以解决回调地狱问题"></a>2.支持链式调用，可以解决回调地狱问题</h4><p>回调地狱：回调函数嵌套调用，外部回调函数异步执行的结果是嵌套的回调执行的条件，这样就造成不便于阅读、不便于异常处理<br>promise所支持的链式调用可以解决这个方案</p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">//成功的回调</span></span><br><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">successCallback</span>(<span class="params">result</span>) </span>&#123;</span><br><span class="line">    <span class="built_in">console</span>.log(<span class="string">"成功了"</span>)</span><br><span class="line">&#125;</span><br><span class="line"><span class="comment">//失败的回调</span></span><br><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">failureCallback</span>(<span class="params">error</span>) </span>&#123;</span><br><span class="line">    <span class="built_in">console</span>.log(<span class="string">"失败了"</span>)</span><br><span class="line">&#125;</span><br><span class="line"><span class="comment">//使用纯回调函数</span></span><br><span class="line">createAudioFileAsync(audio,successCallback,failureCallback)</span><br><span class="line"><span class="comment">/* 1.2. 使用 Promise */</span></span><br><span class="line"><span class="keyword">const</span> promise = createAudioFileAsync(audio);</span><br><span class="line">    setTimeout(<span class="function"><span class="params">()</span> =&gt;</span> &#123; </span><br><span class="line">        promise.then(successCallback, failureCallback); </span><br><span class="line">    &#125;, <span class="number">3000</span>)</span><br><span class="line"><span class="comment">//回调地狱</span></span><br><span class="line"> doSomething(<span class="function"><span class="keyword">function</span>(<span class="params">result</span>) </span>&#123; </span><br><span class="line">     doSomethingElse(result, <span class="function"><span class="keyword">function</span>(<span class="params">newResult</span>) </span>&#123;</span><br><span class="line">         doThirdThing(newResult, <span class="function"><span class="keyword">function</span>(<span class="params">finalResult</span>) </span>&#123;</span><br><span class="line">             <span class="built_in">console</span>.log(<span class="string">'Got the final result: '</span> + finalResult) </span><br><span class="line">             &#125;, failureCallback) </span><br><span class="line">            &#125;, failureCallback) </span><br><span class="line">        &#125;, failureCallback)</span><br><span class="line"> <span class="comment">/* </span></span><br><span class="line"><span class="comment">2.2. 使用promise的链式调用解决回调地狱</span></span><br><span class="line"><span class="comment">*/</span></span><br><span class="line">doSomething()</span><br><span class="line">.then(<span class="function"><span class="keyword">function</span>(<span class="params">result</span>) </span>&#123;</span><br><span class="line">  <span class="keyword">return</span> doSomethingElse(result)</span><br><span class="line">&#125;)</span><br><span class="line">.then(<span class="function"><span class="keyword">function</span>(<span class="params">newResult</span>) </span>&#123;</span><br><span class="line">  <span class="keyword">return</span> doThirdThing(newResult)</span><br><span class="line">&#125;)</span><br><span class="line">.then(<span class="function"><span class="keyword">function</span>(<span class="params">finalResult</span>) </span>&#123;</span><br><span class="line">  <span class="built_in">console</span>.log(<span class="string">'Got the final result: '</span> + finalResult)</span><br><span class="line">&#125;)</span><br><span class="line">.catch(failureCallback)</span><br><span class="line"><span class="comment">/* </span></span><br><span class="line"><span class="comment">2.3. async/await: 回调地狱的终极解决方案</span></span><br><span class="line"><span class="comment">*/</span></span><br><span class="line"><span class="keyword">async</span> <span class="function"><span class="keyword">function</span> <span class="title">request</span>(<span class="params"></span>) </span>&#123;</span><br><span class="line">  <span class="keyword">try</span> &#123;</span><br><span class="line">    <span class="keyword">const</span> result = <span class="keyword">await</span> doSomething()</span><br><span class="line">    <span class="keyword">const</span> newResult = <span class="keyword">await</span> doSomethingElse(result)</span><br><span class="line">    <span class="keyword">const</span> finalResult = <span class="keyword">await</span> doThirdThing(newResult)</span><br><span class="line">    <span class="built_in">console</span>.log(<span class="string">'Got the final result: '</span> + finalResult)</span><br><span class="line">  &#125; <span class="keyword">catch</span> (error) &#123;</span><br><span class="line">    failureCallback(error)</span><br><span class="line">  &#125;</span><br></pre></td></tr></table></figure>
<h3 id="PromiseAPI"><a href="#PromiseAPI" class="headerlink" title="PromiseAPI"></a>PromiseAPI</h3><pre><code>1. Promise构造函数: Promise (excutor) {}
    excutor函数: 同步执行  (resolve, reject) =&gt; {}
    resolve函数: 内部定义成功时我们调用的函数 value =&gt; {}
    reject函数: 内部定义失败时我们调用的函数 reason =&gt; {}
    说明: excutor会在Promise内部立即同步回调,异步操作在执行器中执行

2. Promise.prototype.then方法: (onResolved, onRejected) =&gt; {}
    onResolved函数: 成功的回调函数  (value) =&gt; {}
    onRejected函数: 失败的回调函数 (reason) =&gt; {}
    说明: 指定用于得到成功value的成功回调和用于得到失败reason的失败回调
          返回一个新的promise对象

3. Promise.prototype.catch方法: (onRejected) =&gt; {}
    onRejected函数: 失败的回调函数 (reason) =&gt; {}
    说明: then()的语法糖, 相当于: then(undefined, onRejected)

4. Promise.resolve方法: (value) =&gt; {}
    value: 成功的数据或promise对象
    说明: 返回一个成功/失败的promise对象

5. Promise.reject方法: (reason) =&gt; {}
    reason: 失败的原因
    说明: 返回一个失败的promise对象

6. Promise.all方法: (promises) =&gt; {}
    promises: 包含n个promise的数组
    说明: 返回一个新的promise, 只有所有的promise都成功才成功, 只要有一个失败了就直接失败
7. Promise.race方法: (promises) =&gt; {}
    promises: 包含n个promise的数组
    说明: 返回一个新的promise, 第一个完成的promise的结果状态就是最终的结果状态</code></pre><h3 id="Promise的相关问题"><a href="#Promise的相关问题" class="headerlink" title="Promise的相关问题"></a>Promise的相关问题</h3><pre><code>1.如何改变promise的状态?
  (1)resolve(value): 如果当前是pendding就会变为resolved
  (2)reject(reason): 如果当前是pendding就会变为rejected
  (3)抛出异常: 如果当前是pendding就会变为rejected

2.    一个promise指定多个成功/失败回调函数, 都会调用吗?
  当promise改变为对应状态时都会调用</code></pre><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">const</span> p=<span class="keyword">new</span> <span class="built_in">Promise</span>(<span class="function">(<span class="params">resolve,reject</span>)=&gt;</span>&#123;</span><br><span class="line">    resolve(<span class="number">1</span>)</span><br><span class="line">    <span class="comment">//theow 3</span></span><br><span class="line">&#125;)</span><br><span class="line"><span class="comment">//下面这两个then均会调用</span></span><br><span class="line"> p.then(</span><br><span class="line">      value =&gt; &#123;&#125;,</span><br><span class="line">      reason =&gt; &#123;<span class="built_in">console</span>.log(<span class="string">'reason'</span>, reason)&#125;</span><br><span class="line">    )</span><br><span class="line">p.then(</span><br><span class="line">      value =&gt; &#123;&#125;,</span><br><span class="line">      reason =&gt; &#123;<span class="built_in">console</span>.log(<span class="string">'reason2'</span>, reason)&#125;</span><br><span class="line">    )</span><br></pre></td></tr></table></figure>
<pre><code> 3.改变promise状态和指定回调函数谁先谁后?
  (1)都有可能, 正常情况下是先指定回调再改变状态, 但也可以先改状态再指定回调
  (2)如何先改状态再指定回调?
    ①在执行器中直接调用resolve()/reject()
    ②延迟更长时间才调用then()
  (3)什么时候才能得到数据?
    ①如果先指定的回调, 那当状态发生改变时, 回调函数就会调用, 得到数据
    ②如果先改变的状态, 那当指定回调时, 回调函数就会调用, 得到数据

4.promise.then()返回的新promise的结果状态由什么决定?
  (1)简单表达: 由then()指定的回调函数执行的结果决定
  (2)详细表达:
      ①如果抛出异常, 新promise变为rejected, reason为抛出的异常
      ②如果返回的是非promise的任意值, 新promise变为resolved, value为返回的值
      ③如果返回的是另一个新promise, 此promise的结果就会成为新promise的结果 
5.promise如何串连多个操作任务?
  (1)promise的then()返回一个新的promise, 可以开成then()的链式调用
  (2)通过then的链式调用串连多个同步/异步任务
6.promise异常传/穿透?
  (1)当使用promise的then链式调用时, 可以在最后指定失败的回调, 
  (2)前面任何操作出了异常, 都会传到最后失败的回调中处理
7.中断promise链?
  (1)当使用promise的then链式调用时, 在中间中断, 不再调用后面的回调函数
  (2)办法: 在回调函数中返回一个pendding状态的promise对象
    new Promise(() =&gt; {}) 返回一个pending的promise  中断promise链</code></pre><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br><span class="line">83</span><br><span class="line">84</span><br><span class="line">85</span><br><span class="line">86</span><br><span class="line">87</span><br><span class="line">88</span><br><span class="line">89</span><br><span class="line">90</span><br><span class="line">91</span><br><span class="line">92</span><br><span class="line">93</span><br><span class="line">94</span><br><span class="line">95</span><br><span class="line">96</span><br><span class="line">97</span><br><span class="line">98</span><br><span class="line">99</span><br><span class="line">100</span><br><span class="line">101</span><br><span class="line">102</span><br><span class="line">103</span><br><span class="line">104</span><br><span class="line">105</span><br><span class="line">106</span><br><span class="line">107</span><br><span class="line">108</span><br><span class="line">109</span><br><span class="line">110</span><br><span class="line">111</span><br><span class="line">112</span><br><span class="line">113</span><br><span class="line">114</span><br><span class="line">115</span><br><span class="line">116</span><br><span class="line">117</span><br><span class="line">118</span><br><span class="line">119</span><br><span class="line">120</span><br><span class="line">121</span><br><span class="line">122</span><br><span class="line">123</span><br><span class="line">124</span><br><span class="line">125</span><br><span class="line">126</span><br><span class="line">127</span><br><span class="line">128</span><br><span class="line">129</span><br><span class="line">130</span><br><span class="line">131</span><br><span class="line">132</span><br><span class="line">133</span><br><span class="line">134</span><br><span class="line">135</span><br><span class="line">136</span><br><span class="line">137</span><br><span class="line">138</span><br><span class="line">139</span><br><span class="line">140</span><br><span class="line">141</span><br><span class="line">142</span><br><span class="line">143</span><br><span class="line">144</span><br><span class="line">145</span><br><span class="line">146</span><br><span class="line">147</span><br><span class="line">148</span><br><span class="line">149</span><br><span class="line">150</span><br><span class="line">151</span><br><span class="line">152</span><br><span class="line">153</span><br><span class="line">154</span><br><span class="line">155</span><br><span class="line">156</span><br><span class="line">157</span><br><span class="line">158</span><br><span class="line">159</span><br><span class="line">160</span><br><span class="line">161</span><br><span class="line">162</span><br><span class="line">163</span><br><span class="line">164</span><br><span class="line">165</span><br><span class="line">166</span><br><span class="line">167</span><br><span class="line">168</span><br><span class="line">169</span><br><span class="line">170</span><br><span class="line">171</span><br><span class="line">172</span><br><span class="line">173</span><br><span class="line">174</span><br><span class="line">175</span><br><span class="line">176</span><br><span class="line">177</span><br><span class="line">178</span><br><span class="line">179</span><br><span class="line">180</span><br><span class="line">181</span><br><span class="line">182</span><br><span class="line">183</span><br><span class="line">184</span><br><span class="line">185</span><br><span class="line">186</span><br><span class="line">187</span><br><span class="line">188</span><br><span class="line">189</span><br><span class="line">190</span><br><span class="line">191</span><br><span class="line">192</span><br><span class="line">193</span><br><span class="line">194</span><br><span class="line">195</span><br><span class="line">196</span><br><span class="line">197</span><br><span class="line">198</span><br><span class="line">199</span><br><span class="line">200</span><br><span class="line">201</span><br><span class="line">202</span><br><span class="line">203</span><br><span class="line">204</span><br><span class="line">205</span><br><span class="line">206</span><br><span class="line">207</span><br><span class="line">208</span><br><span class="line">209</span><br><span class="line">210</span><br><span class="line">211</span><br><span class="line">212</span><br><span class="line">213</span><br><span class="line">214</span><br><span class="line">215</span><br><span class="line">216</span><br><span class="line">217</span><br><span class="line">218</span><br><span class="line">219</span><br><span class="line">220</span><br><span class="line">221</span><br><span class="line">222</span><br><span class="line">223</span><br><span class="line">224</span><br><span class="line">225</span><br><span class="line">226</span><br><span class="line">227</span><br><span class="line">228</span><br><span class="line">229</span><br><span class="line">230</span><br><span class="line">231</span><br><span class="line">232</span><br><span class="line">233</span><br><span class="line">234</span><br><span class="line">235</span><br><span class="line">236</span><br><span class="line">237</span><br><span class="line">238</span><br><span class="line">239</span><br><span class="line">240</span><br><span class="line">241</span><br><span class="line">242</span><br><span class="line">243</span><br><span class="line">244</span><br><span class="line">245</span><br><span class="line">246</span><br><span class="line">247</span><br><span class="line">248</span><br><span class="line">249</span><br><span class="line">250</span><br><span class="line">251</span><br><span class="line">252</span><br><span class="line">253</span><br><span class="line">254</span><br><span class="line">255</span><br><span class="line">256</span><br><span class="line">257</span><br><span class="line">258</span><br><span class="line">259</span><br><span class="line">260</span><br><span class="line">261</span><br><span class="line">262</span><br><span class="line">263</span><br><span class="line">264</span><br><span class="line">265</span><br><span class="line">266</span><br><span class="line">267</span><br><span class="line">268</span><br><span class="line">269</span><br><span class="line">270</span><br><span class="line">271</span><br><span class="line">272</span><br><span class="line">273</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">/* </span></span><br><span class="line"><span class="comment">自定义Promise函数模块: IIFE</span></span><br><span class="line"><span class="comment">*/</span></span><br><span class="line">(<span class="function"><span class="keyword">function</span> (<span class="params">window</span>) </span>&#123;</span><br><span class="line"></span><br><span class="line">  <span class="keyword">const</span> PENDING = <span class="string">'pending'</span></span><br><span class="line">  <span class="keyword">const</span> RESOLVED = <span class="string">'resolved'</span></span><br><span class="line">  <span class="keyword">const</span> REJECTED = <span class="string">'rejected'</span></span><br><span class="line">  </span><br><span class="line">  <span class="comment">/* </span></span><br><span class="line"><span class="comment">  Promise构造函数</span></span><br><span class="line"><span class="comment">  excutor: 执行器函数(同步执行)</span></span><br><span class="line"><span class="comment">  */</span></span><br><span class="line">  <span class="function"><span class="keyword">function</span> <span class="title">Promise</span>(<span class="params">excutor</span>) </span>&#123;</span><br><span class="line">    <span class="comment">// 将当前promise对象保存起来</span></span><br><span class="line">    <span class="keyword">const</span> self = <span class="keyword">this</span></span><br><span class="line">    self.status = PENDING <span class="comment">// 给promise对象指定status属性, 初始值为pending</span></span><br><span class="line">    self.data = <span class="literal">undefined</span> <span class="comment">// 给promise对象指定一个用于存储结果数据的属性</span></span><br><span class="line">    self.callbacks = [] <span class="comment">// 每个元素的结构: &#123; onResolved() &#123;&#125;, onRejected() &#123;&#125;&#125;</span></span><br><span class="line"></span><br><span class="line">    <span class="function"><span class="keyword">function</span> <span class="title">resolve</span> (<span class="params">value</span>) </span>&#123;</span><br><span class="line">      <span class="comment">// 如果当前状态不是pending, 直接结束</span></span><br><span class="line">      <span class="keyword">if</span> (self.status!==PENDING) &#123;</span><br><span class="line">        <span class="keyword">return</span></span><br><span class="line">      &#125;</span><br><span class="line"></span><br><span class="line">      <span class="comment">// 将状态改为resolved</span></span><br><span class="line">      self.status = RESOLVED</span><br><span class="line">      <span class="comment">// 保存value数据</span></span><br><span class="line">      self.data = value</span><br><span class="line">      <span class="comment">// 如果有待执行callback函数, 立即异步执行回调函数onResolved</span></span><br><span class="line">      <span class="keyword">if</span> (self.callbacks.length&gt;<span class="number">0</span>) &#123;</span><br><span class="line">        setTimeout(<span class="function"><span class="params">()</span> =&gt;</span> &#123; <span class="comment">// 放入队列中执行所有成功的回调</span></span><br><span class="line">          self.callbacks.forEach(<span class="function"><span class="params">calbacksObj</span> =&gt;</span> &#123;</span><br><span class="line">            calbacksObj.onResolved(value)</span><br><span class="line">          &#125;) </span><br><span class="line">        &#125;);</span><br><span class="line">      &#125;</span><br><span class="line"></span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="function"><span class="keyword">function</span> <span class="title">reject</span> (<span class="params">reason</span>) </span>&#123;</span><br><span class="line">      <span class="comment">// 如果当前状态不是pending, 直接结束</span></span><br><span class="line">      <span class="keyword">if</span> (self.status!==PENDING) &#123;</span><br><span class="line">        <span class="keyword">return</span></span><br><span class="line">      &#125;</span><br><span class="line"></span><br><span class="line">      <span class="comment">// 将状态改为rejected</span></span><br><span class="line">      self.status = REJECTED</span><br><span class="line">      <span class="comment">// 保存value数据</span></span><br><span class="line">      self.data = reason</span><br><span class="line">      <span class="comment">// 如果有待执行callback函数, 立即异步执行回调函数onRejected</span></span><br><span class="line">      <span class="keyword">if</span> (self.callbacks.length&gt;<span class="number">0</span>) &#123;</span><br><span class="line">        setTimeout(<span class="function"><span class="params">()</span> =&gt;</span> &#123; <span class="comment">// 放入队列中执行所有成功的回调</span></span><br><span class="line">          self.callbacks.forEach(<span class="function"><span class="params">calbacksObj</span> =&gt;</span> &#123;</span><br><span class="line">            calbacksObj.onRejected(reason)</span><br><span class="line">          &#125;) </span><br><span class="line">        &#125;);</span><br><span class="line">      &#125;</span><br><span class="line">    &#125;</span><br><span class="line">    </span><br><span class="line">    <span class="comment">// 立即同步执行excutor</span></span><br><span class="line">    <span class="keyword">try</span> &#123;</span><br><span class="line">      excutor(resolve, reject)</span><br><span class="line">    &#125; <span class="keyword">catch</span> (error) &#123; <span class="comment">// 如果执行器抛出异常, promise对象变为rejected状态</span></span><br><span class="line">      reject(error)</span><br><span class="line">    &#125;</span><br><span class="line">    </span><br><span class="line">  &#125;</span><br><span class="line"></span><br><span class="line">  <span class="comment">/* </span></span><br><span class="line"><span class="comment">  Promise原型对象的then()</span></span><br><span class="line"><span class="comment">  指定成功和失败的回调函数</span></span><br><span class="line"><span class="comment">  返回一个新的promise对象</span></span><br><span class="line"><span class="comment">  返回promise的结果由onResolved/onRejected执行结果决定</span></span><br><span class="line"><span class="comment"></span></span><br><span class="line"><span class="comment">  */</span></span><br><span class="line">  <span class="built_in">Promise</span>.prototype.then = <span class="function"><span class="keyword">function</span> (<span class="params">onResolved, onRejected</span>) </span>&#123;</span><br><span class="line">    <span class="keyword">const</span> self = <span class="keyword">this</span></span><br><span class="line"></span><br><span class="line">    <span class="comment">// 指定回调函数的默认值(必须是函数)</span></span><br><span class="line">    onResolved = <span class="keyword">typeof</span> onResolved===<span class="string">'function'</span> ? onResolved : <span class="function"><span class="params">value</span> =&gt;</span> value</span><br><span class="line">    onRejected = <span class="keyword">typeof</span> onRejected===<span class="string">'function'</span> ? onRejected : <span class="function"><span class="params">reason</span> =&gt;</span> &#123;<span class="keyword">throw</span> reason&#125;</span><br><span class="line"></span><br><span class="line"></span><br><span class="line">    <span class="comment">// 返回一个新的promise</span></span><br><span class="line">    <span class="keyword">return</span> <span class="keyword">new</span> <span class="built_in">Promise</span>(<span class="function">(<span class="params">resolve, reject</span>) =&gt;</span> &#123;</span><br><span class="line"></span><br><span class="line">      <span class="comment">/* </span></span><br><span class="line"><span class="comment">      执行指定的回调函数</span></span><br><span class="line"><span class="comment">      根据执行的结果改变return的promise的状态/数据</span></span><br><span class="line"><span class="comment">      */</span></span><br><span class="line">      <span class="function"><span class="keyword">function</span> <span class="title">handle</span>(<span class="params">callback</span>) </span>&#123;</span><br><span class="line">        <span class="comment">/* </span></span><br><span class="line"><span class="comment">        返回promise的结果由onResolved/onRejected执行结果决定</span></span><br><span class="line"><span class="comment">        1. 抛出异常, 返回promise的结果为失败, reason为异常</span></span><br><span class="line"><span class="comment">        2. 返回的是promise, 返回promise的结果就是这个结果</span></span><br><span class="line"><span class="comment">        3. 返回的不是promise, 返回promise为成功, value就是返回值</span></span><br><span class="line"><span class="comment">        */</span></span><br><span class="line">        <span class="keyword">try</span> &#123;</span><br><span class="line">          <span class="keyword">const</span> result = callback(self.data)</span><br><span class="line">          <span class="keyword">if</span> (result <span class="keyword">instanceof</span> <span class="built_in">Promise</span>) &#123; <span class="comment">// 2. 返回的是promise, 返回promise的结果就是这个结果</span></span><br><span class="line">            <span class="comment">/* </span></span><br><span class="line"><span class="comment">            result.then(</span></span><br><span class="line"><span class="comment">              value =&gt; resolve(vlaue),</span></span><br><span class="line"><span class="comment">              reason =&gt; reject(reason)</span></span><br><span class="line"><span class="comment">            ) */</span></span><br><span class="line">            result.then(resolve, reject)</span><br><span class="line">          &#125; <span class="keyword">else</span> &#123; <span class="comment">// 3. 返回的不是promise, 返回promise为成功, value就是返回值</span></span><br><span class="line">            resolve(result)</span><br><span class="line">          &#125;</span><br><span class="line"></span><br><span class="line">        &#125; <span class="keyword">catch</span> (error) &#123; <span class="comment">// 1. 抛出异常, 返回promise的结果为失败, reason为异常</span></span><br><span class="line">          reject(error)</span><br><span class="line">        &#125;</span><br><span class="line">      &#125;</span><br><span class="line"></span><br><span class="line">      <span class="comment">// 当前promise的状态是resolved</span></span><br><span class="line">      <span class="keyword">if</span> (self.status===RESOLVED) &#123;</span><br><span class="line">        <span class="comment">// 立即异步执行成功的回调函数</span></span><br><span class="line">        setTimeout(<span class="function"><span class="params">()</span> =&gt;</span> &#123;</span><br><span class="line">          handle(onResolved)</span><br><span class="line">        &#125;)</span><br><span class="line">      &#125; <span class="keyword">else</span> <span class="keyword">if</span> (self.status===REJECTED) &#123; <span class="comment">// 当前promise的状态是rejected</span></span><br><span class="line">        <span class="comment">// 立即异步执行失败的回调函数</span></span><br><span class="line">        setTimeout(<span class="function"><span class="params">()</span> =&gt;</span> &#123;</span><br><span class="line">          handle(onRejected)</span><br><span class="line">        &#125;)</span><br><span class="line">      &#125; <span class="keyword">else</span> &#123; <span class="comment">// 当前promise的状态是pending</span></span><br><span class="line">        <span class="comment">// 将成功和失败的回调函数保存callbacks容器中缓存起来</span></span><br><span class="line">        self.callbacks.push(&#123;</span><br><span class="line">          onResolved (value) &#123;</span><br><span class="line">            handle(onResolved)</span><br><span class="line">          &#125;,</span><br><span class="line">          onRejected (reason) &#123;</span><br><span class="line">            handle(onRejected)</span><br><span class="line">          &#125;</span><br><span class="line">        &#125;)</span><br><span class="line">      &#125;</span><br><span class="line">    &#125;)</span><br><span class="line">  &#125;</span><br><span class="line"><span class="comment">/* </span></span><br><span class="line"><span class="comment">  function fn(event) &#123;</span></span><br><span class="line"><span class="comment">    </span></span><br><span class="line"><span class="comment">  &#125;</span></span><br><span class="line"><span class="comment">  div.onclick = function (event)&#123;</span></span><br><span class="line"><span class="comment">    fn(event)</span></span><br><span class="line"><span class="comment">  &#125;</span></span><br><span class="line"><span class="comment">  div.onclick = fn</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line">  <span class="comment">/* </span></span><br><span class="line"><span class="comment">  Promise原型对象的catch()</span></span><br><span class="line"><span class="comment">  指定失败的回调函数</span></span><br><span class="line"><span class="comment">  返回一个新的promise对象</span></span><br><span class="line"><span class="comment">  */</span></span><br><span class="line">  <span class="built_in">Promise</span>.prototype.catch = <span class="function"><span class="keyword">function</span> (<span class="params">onRejected</span>) </span>&#123;</span><br><span class="line">    <span class="keyword">return</span> <span class="keyword">this</span>.then(<span class="literal">undefined</span>, onRejected)</span><br><span class="line">  &#125;</span><br><span class="line"></span><br><span class="line">  <span class="comment">/* </span></span><br><span class="line"><span class="comment">  Promise函数对象的resolve方法</span></span><br><span class="line"><span class="comment">  返回一个指定结果的成功的promise</span></span><br><span class="line"><span class="comment">  */</span></span><br><span class="line">  <span class="built_in">Promise</span>.resolve = <span class="function"><span class="keyword">function</span> (<span class="params">value</span>) </span>&#123;</span><br><span class="line">    <span class="comment">// 返回一个成功/失败的promise</span></span><br><span class="line">    <span class="keyword">return</span> <span class="keyword">new</span> <span class="built_in">Promise</span>(<span class="function">(<span class="params">resolve, reject</span>) =&gt;</span> &#123;</span><br><span class="line">      <span class="comment">// value是promise</span></span><br><span class="line">      <span class="keyword">if</span> (value <span class="keyword">instanceof</span> <span class="built_in">Promise</span>) &#123; <span class="comment">// 使用value的结果作为promise的结果</span></span><br><span class="line">        value.then(resolve, reject)</span><br><span class="line">      &#125; <span class="keyword">else</span> &#123; <span class="comment">// value不是promise  =&gt; promise变为成功, 数据是value</span></span><br><span class="line">        resolve(value)</span><br><span class="line">      &#125;</span><br><span class="line">    &#125;)</span><br><span class="line">  &#125;</span><br><span class="line"></span><br><span class="line">  <span class="comment">/* </span></span><br><span class="line"><span class="comment">  Promise函数对象的reject方法</span></span><br><span class="line"><span class="comment">  返回一个指定reason的失败的promise</span></span><br><span class="line"><span class="comment">  */</span></span><br><span class="line">  <span class="built_in">Promise</span>.reject = <span class="function"><span class="keyword">function</span> (<span class="params">reason</span>) </span>&#123;</span><br><span class="line">    <span class="comment">// 返回一个失败的promise</span></span><br><span class="line">    <span class="keyword">return</span> <span class="keyword">new</span> <span class="built_in">Promise</span>(<span class="function">(<span class="params">resolve, reject</span>) =&gt;</span> &#123;</span><br><span class="line">      reject(reason)</span><br><span class="line">    &#125;)</span><br><span class="line">  &#125;</span><br><span class="line"></span><br><span class="line">  <span class="comment">/* </span></span><br><span class="line"><span class="comment">  Promise函数对象的all方法</span></span><br><span class="line"><span class="comment">  返回一个promise, 只有当所有proimse都成功时才成功, 否则只要有一个失败的就失败</span></span><br><span class="line"><span class="comment">  */</span></span><br><span class="line">  <span class="built_in">Promise</span>.all = <span class="function"><span class="keyword">function</span> (<span class="params">promises</span>) </span>&#123;</span><br><span class="line">    <span class="comment">// 用来保存所有成功value的数组</span></span><br><span class="line">    <span class="keyword">const</span> values = <span class="keyword">new</span> <span class="built_in">Array</span>(promises.length) </span><br><span class="line">    <span class="comment">// 用来保存成功promise的数量</span></span><br><span class="line">    <span class="keyword">let</span> resolvedCount = <span class="number">0</span></span><br><span class="line">    <span class="comment">// 返回一个新的promise</span></span><br><span class="line">    <span class="keyword">return</span> <span class="keyword">new</span> <span class="built_in">Promise</span>(<span class="function">(<span class="params">resolve, reject</span>) =&gt;</span> &#123;</span><br><span class="line">      <span class="comment">// 遍历promises获取每个promise的结果</span></span><br><span class="line">      promises.forEach(<span class="function">(<span class="params">p, index</span>) =&gt;</span> &#123;</span><br><span class="line">        <span class="built_in">Promise</span>.resolve(p).then(</span><br><span class="line">          value =&gt; &#123;</span><br><span class="line">            resolvedCount++ <span class="comment">// 成功的数量加1</span></span><br><span class="line">            <span class="comment">// p成功, 将成功的vlaue保存vlaues</span></span><br><span class="line">            <span class="comment">// values.push(value)</span></span><br><span class="line">            values[index] = value</span><br><span class="line"></span><br><span class="line">            <span class="comment">// 如果全部成功了, 将return的promise改变成功</span></span><br><span class="line">            <span class="keyword">if</span> (resolvedCount===promises.length) &#123;</span><br><span class="line">              resolve(values)</span><br><span class="line">            &#125;</span><br><span class="line"></span><br><span class="line">          &#125;,</span><br><span class="line">          reason =&gt; &#123; <span class="comment">// 只要一个失败了, return的promise就失败</span></span><br><span class="line">            reject(reason)</span><br><span class="line">          &#125;</span><br><span class="line">        )</span><br><span class="line">      &#125;)</span><br><span class="line">    &#125;)</span><br><span class="line">  &#125;</span><br><span class="line"></span><br><span class="line">  <span class="comment">/* </span></span><br><span class="line"><span class="comment">  Promise函数对象的race方法</span></span><br><span class="line"><span class="comment">  返回一个promise, 其结果由第一个完成的promise决定</span></span><br><span class="line"><span class="comment">  */</span></span><br><span class="line">  <span class="built_in">Promise</span>.race = <span class="function"><span class="keyword">function</span> (<span class="params">promises</span>) </span>&#123;</span><br><span class="line">    <span class="comment">// 返回一个promise</span></span><br><span class="line">    <span class="keyword">return</span> <span class="keyword">new</span> <span class="built_in">Promise</span>(<span class="function">(<span class="params">resolve, reject</span>) =&gt;</span> &#123;</span><br><span class="line">      <span class="comment">// 遍历promises获取每个promise的结果</span></span><br><span class="line">      promises.forEach(<span class="function">(<span class="params">p, index</span>) =&gt;</span> &#123;</span><br><span class="line">        <span class="built_in">Promise</span>.resolve(p).then(</span><br><span class="line">          value =&gt; &#123;<span class="comment">// 一旦有成功了, 将return变为成功</span></span><br><span class="line">            resolve(value)</span><br><span class="line">          &#125;,</span><br><span class="line">          reason =&gt; &#123; <span class="comment">// 一旦有失败了, 将return变为失败</span></span><br><span class="line">            reject(reason)</span><br><span class="line">          &#125;</span><br><span class="line">        )</span><br><span class="line">      &#125;)</span><br><span class="line">    &#125;)</span><br><span class="line">  &#125;</span><br><span class="line"></span><br><span class="line">  <span class="comment">/* </span></span><br><span class="line"><span class="comment">  返回一个promise对象, 它在指定的时间后才确定结果</span></span><br><span class="line"><span class="comment">  */</span></span><br><span class="line">  <span class="built_in">Promise</span>.resolveDelay = <span class="function"><span class="keyword">function</span> (<span class="params">value, time</span>) </span>&#123;</span><br><span class="line">    <span class="comment">// 返回一个成功/失败的promise</span></span><br><span class="line">    <span class="keyword">return</span> <span class="keyword">new</span> <span class="built_in">Promise</span>(<span class="function">(<span class="params">resolve, reject</span>) =&gt;</span> &#123;</span><br><span class="line">      setTimeout(<span class="function"><span class="params">()</span> =&gt;</span> &#123;</span><br><span class="line">        <span class="comment">// value是promise</span></span><br><span class="line">        <span class="keyword">if</span> (value <span class="keyword">instanceof</span> <span class="built_in">Promise</span>) &#123; <span class="comment">// 使用value的结果作为promise的结果</span></span><br><span class="line">          value.then(resolve, reject)</span><br><span class="line">        &#125; <span class="keyword">else</span> &#123; <span class="comment">// value不是promise  =&gt; promise变为成功, 数据是value</span></span><br><span class="line">          resolve(value)</span><br><span class="line">        &#125;</span><br><span class="line">      &#125;, time)</span><br><span class="line">    &#125;)</span><br><span class="line">  &#125;</span><br><span class="line"></span><br><span class="line">  <span class="comment">/* </span></span><br><span class="line"><span class="comment">  返回一个promise对象, 它在指定的时间后才失败</span></span><br><span class="line"><span class="comment">  */</span></span><br><span class="line">  <span class="built_in">Promise</span>.rejectDelay = <span class="function"><span class="keyword">function</span> (<span class="params">reason, time</span>) </span>&#123;</span><br><span class="line">    <span class="comment">// 返回一个失败的promise</span></span><br><span class="line">    <span class="keyword">return</span> <span class="keyword">new</span> <span class="built_in">Promise</span>(<span class="function">(<span class="params">resolve, reject</span>) =&gt;</span> &#123;</span><br><span class="line">      setTimeout(<span class="function"><span class="params">()</span> =&gt;</span> &#123;</span><br><span class="line">        reject(reason)</span><br><span class="line">      &#125;, time)</span><br><span class="line">    &#125;)</span><br><span class="line">  &#125;</span><br><span class="line"></span><br><span class="line">  <span class="comment">// 向外暴露Promise函数</span></span><br><span class="line">  <span class="built_in">window</span>.Promise = <span class="built_in">Promise</span></span><br><span class="line">&#125;)(<span class="built_in">window</span>)</span><br></pre></td></tr></table></figure>

          
        
      
    </div>
    
    
    

    

    

    

    <footer class="post-footer">
      

      

      

      
      
        <div class="post-eof"></div>
      
    </footer>
  </div>
  
  
  
  </article>


    
      

  

  
  
  

  <article class="post post-type-normal" itemscope itemtype="http://schema.org/Article">
  
  
  
  <div class="post-block">
    <link itemprop="mainEntityOfPage" href="https://liang34.github.io/Liang34/Liang34/2020/03/08/closure/">

    <span hidden itemprop="author" itemscope itemtype="http://schema.org/Person">
      <meta itemprop="name" content="LiangJH">
      <meta itemprop="description" content="">
      <meta itemprop="image" content="/Liang34/images/avatar.jpg">
    </span>

    <span hidden itemprop="publisher" itemscope itemtype="http://schema.org/Organization">
      <meta itemprop="name" content="liang34">
    </span>

    
      <header class="post-header">

        
        
          <h1 class="post-title" itemprop="name headline">
                
                <a class="post-title-link" href="/Liang34/2020/03/08/closure/" itemprop="url">closure</a></h1>
        

        <div class="post-meta">
          <span class="post-time">
            
              <span class="post-meta-item-icon">
                <i class="fa fa-calendar-o"></i>
              </span>
              
                <span class="post-meta-item-text">发表于</span>
              
              <time title="创建于" itemprop="dateCreated datePublished" datetime="2020-03-08T20:48:09+08:00">
                2020-03-08
              </time>
            

            

            
          </span>

          
            <span class="post-category" >
            
              <span class="post-meta-divider">|</span>
            
              <span class="post-meta-item-icon">
                <i class="fa fa-folder-o"></i>
              </span>
              
                <span class="post-meta-item-text">分类于</span>
              
              
                <span itemprop="about" itemscope itemtype="http://schema.org/Thing">
                  <a href="/Liang34/categories/JavaScript/" itemprop="url" rel="index">
                    <span itemprop="name">JavaScript</span>
                  </a>
                </span>

                
                
              
            </span>
          

          
            
          

          
          

          

          

          

        </div>
      </header>
    

    
    
    
    <div class="post-body" itemprop="articleBody">

      
      

      
        
          
            <h1 id="闭包"><a href="#闭包" class="headerlink" title="闭包"></a>闭包</h1><h3 id="闭包的产生：当函数可以记住并访问所在的词法作用域时，就产生了闭包，即使函数是在当前词法作用域之外执行"><a href="#闭包的产生：当函数可以记住并访问所在的词法作用域时，就产生了闭包，即使函数是在当前词法作用域之外执行" class="headerlink" title="闭包的产生：当函数可以记住并访问所在的词法作用域时，就产生了闭包，即使函数是在当前词法作用域之外执行"></a>闭包的产生：当函数可以记住并访问所在的词法作用域时，就产生了闭包，即使函数是在当前词法作用域之外执行</h3><hr>
<p>实现闭包的三种方式：</p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">//一：通过return返回内部函数</span></span><br><span class="line"> <span class="function"><span class="keyword">function</span> <span class="title">foo</span>(<span class="params"></span>)</span>&#123;</span><br><span class="line">     <span class="keyword">var</span> a=<span class="number">2</span>;</span><br><span class="line">     <span class="function"><span class="keyword">function</span> <span class="title">bar</span>(<span class="params"></span>)</span>&#123;</span><br><span class="line">         <span class="built_in">console</span>.log(a);</span><br><span class="line">     &#125;</span><br><span class="line">     <span class="keyword">return</span> bar;</span><br><span class="line"> &#125;</span><br><span class="line"> <span class="keyword">var</span> baz=foo();</span><br><span class="line"> baz();<span class="comment">//闭包的效果</span></span><br><span class="line"> <span class="comment">//在foo,执行完后，由于bar()本身仍在使用，故不会被回收</span></span><br><span class="line"> <span class="comment">//二：将内部函数当作实参</span></span><br><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">foo</span>(<span class="params"></span>)</span>&#123;</span><br><span class="line">    <span class="keyword">var</span> a=<span class="number">2</span>;</span><br><span class="line">    <span class="function"><span class="keyword">function</span> <span class="title">baz</span>(<span class="params"></span>)</span>&#123;</span><br><span class="line">        <span class="built_in">console</span>.log(a);</span><br><span class="line">    &#125;</span><br><span class="line">    bar(baz);</span><br><span class="line">&#125;</span><br><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">bar</span>(<span class="params">fn</span>)</span>&#123;</span><br><span class="line">    fn();</span><br><span class="line">&#125;</span><br><span class="line">foo()</span><br><span class="line"><span class="comment">//三.将内部函数赋值到另外一个变量当中</span></span><br><span class="line"><span class="keyword">var</span> fn;</span><br><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">foo1</span>(<span class="params"></span>)</span>&#123;</span><br><span class="line">    <span class="keyword">var</span> b=<span class="number">3</span>;</span><br><span class="line">    <span class="function"><span class="keyword">function</span> <span class="title">baz1</span>(<span class="params"></span>)</span>&#123;</span><br><span class="line">        <span class="built_in">console</span>.log(b);</span><br><span class="line">    &#125;</span><br><span class="line">    fn=baz1;</span><br><span class="line">&#125;</span><br><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">bar1</span>(<span class="params"></span>)</span>&#123;</span><br><span class="line">    fn();</span><br><span class="line">&#125;</span><br><span class="line">foo1()</span><br><span class="line">bar1()</span><br></pre></td></tr></table></figure>
<h4 id="应用：在定时器，事件监听器，ajax请求，跨窗口通信，web-Workers或者任何其他的异步或者-同步-任务中，只要使用了回调函数，就是在使用了闭包"><a href="#应用：在定时器，事件监听器，ajax请求，跨窗口通信，web-Workers或者任何其他的异步或者-同步-任务中，只要使用了回调函数，就是在使用了闭包" class="headerlink" title="应用：在定时器，事件监听器，ajax请求，跨窗口通信，web Workers或者任何其他的异步或者(同步)任务中，只要使用了回调函数，就是在使用了闭包"></a>应用：在定时器，事件监听器，ajax请求，跨窗口通信，web Workers或者任何其他的异步或者(同步)任务中，只要使用了回调函数，就是在使用了闭包</h4><p>闭包与循环</p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">for</span>(<span class="keyword">var</span> i=<span class="number">1</span>; i&lt;=<span class="number">5</span>;i++)&#123;</span><br><span class="line">    setTimeout(<span class="function"><span class="keyword">function</span>  <span class="title">timer</span>(<span class="params"></span>)</span>&#123;</span><br><span class="line">        <span class="built_in">console</span>.log(i);</span><br><span class="line">    &#125;,i*<span class="number">1000</span>)</span><br><span class="line">&#125;</span><br><span class="line"><span class="comment">/*我们想要的是这都段代码会每秒一次的频率输出1...5实际上这都段代码会每秒一次的频率输出五次6，事实上，当定时器运行时即使每个迭代中执行的时setTimeout(...,0),</span></span><br><span class="line"><span class="comment">    所有的回调函数依然是循环结束后才会被执行，故每次都会输出6来</span></span><br><span class="line"><span class="comment">    怎么决解呢？这样做的缺陷在于循环中的五个函数都是在各个迭代中分别定义的，但是他们都被封闭在一个共享的全局作用域中，实际中只有一个i，</span></span><br><span class="line"><span class="comment">    所以，我们需要更多的闭包作用域，特别是在循环过程中每个迭代都需要一个闭包作用域，所以，我们先想到了IIFE创建作用域： */</span></span><br><span class="line">    <span class="keyword">for</span>(<span class="keyword">var</span> i=<span class="number">1</span>; i&lt;=<span class="number">5</span>;i++)&#123;</span><br><span class="line">        (<span class="function"><span class="keyword">function</span>(<span class="params"></span>)</span>&#123;</span><br><span class="line">            setTimeout(<span class="function"><span class="keyword">function</span>  <span class="title">timer</span>(<span class="params"></span>)</span>&#123;</span><br><span class="line">                <span class="built_in">console</span>.log(i);</span><br><span class="line">            &#125;,i*<span class="number">1000</span>)</span><br><span class="line">        &#125;)();</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="comment">/*但这样还是不行，因为我们的IIFE只是一个什么都没有的作用域，他需要一点实际内容才能为我们所用，他需要自己的变量，用来在迭代中储存i的值 */</span></span><br><span class="line">    <span class="keyword">for</span>(<span class="keyword">var</span> i=<span class="number">1</span>; i&lt;=<span class="number">5</span>;i++)&#123;</span><br><span class="line">        (<span class="function"><span class="keyword">function</span>(<span class="params"></span>)</span>&#123;</span><br><span class="line">            <span class="keyword">var</span> j=i;</span><br><span class="line">            setTimeout(<span class="function"><span class="keyword">function</span>  <span class="title">timer</span>(<span class="params"></span>)</span>&#123;</span><br><span class="line">                <span class="built_in">console</span>.log(j);</span><br><span class="line">            &#125;,j*<span class="number">1000</span>)</span><br><span class="line">        &#125;)();</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="comment">/*这次终于可以了，当然可以做一些改进 */</span></span><br><span class="line">    <span class="keyword">for</span>(<span class="keyword">var</span> i=<span class="number">1</span>; i&lt;=<span class="number">5</span>;i++)&#123;</span><br><span class="line">        (<span class="function"><span class="keyword">function</span>(<span class="params">i</span>)</span>&#123;</span><br><span class="line">            setTimeout(<span class="function"><span class="keyword">function</span>  <span class="title">timer</span>(<span class="params"></span>)</span>&#123;</span><br><span class="line">                <span class="built_in">console</span>.log(<span class="string">"*************"</span>)</span><br><span class="line">                <span class="built_in">console</span>.log(i);</span><br><span class="line">            &#125;,i*<span class="number">1000</span>)</span><br><span class="line">        &#125;)(i);</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="comment">/*当然，我们也可以将这个块转换为一个可以被关闭的作用域，利用let可以使每次迭代都会声明一次i，</span></span><br><span class="line"><span class="comment">    随后的每次迭代都会使用上一个迭代结束的值来初始化这个变量 */</span></span><br><span class="line"><span class="keyword">for</span>(<span class="keyword">let</span> i=<span class="number">1</span>; i&lt;=<span class="number">5</span>;i++)&#123;</span><br><span class="line">    setTimeout(<span class="function"><span class="keyword">function</span>  <span class="title">timer</span>(<span class="params"></span>)</span>&#123;</span><br><span class="line">        <span class="built_in">console</span>.log(i);</span><br><span class="line">    &#125;,i*<span class="number">1000</span>)</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>


          
        
      
    </div>
    
    
    

    

    

    

    <footer class="post-footer">
      

      

      

      
      
        <div class="post-eof"></div>
      
    </footer>
  </div>
  
  
  
  </article>


    
      

  

  
  
  

  <article class="post post-type-normal" itemscope itemtype="http://schema.org/Article">
  
  
  
  <div class="post-block">
    <link itemprop="mainEntityOfPage" href="https://liang34.github.io/Liang34/Liang34/2020/03/02/selectOrder/">

    <span hidden itemprop="author" itemscope itemtype="http://schema.org/Person">
      <meta itemprop="name" content="LiangJH">
      <meta itemprop="description" content="">
      <meta itemprop="image" content="/Liang34/images/avatar.jpg">
    </span>

    <span hidden itemprop="publisher" itemscope itemtype="http://schema.org/Organization">
      <meta itemprop="name" content="liang34">
    </span>

    
      <header class="post-header">

        
        
          <h1 class="post-title" itemprop="name headline">
                
                <a class="post-title-link" href="/Liang34/2020/03/02/selectOrder/" itemprop="url">selectOrder</a></h1>
        

        <div class="post-meta">
          <span class="post-time">
            
              <span class="post-meta-item-icon">
                <i class="fa fa-calendar-o"></i>
              </span>
              
                <span class="post-meta-item-text">发表于</span>
              
              <time title="创建于" itemprop="dateCreated datePublished" datetime="2020-03-02T17:33:16+08:00">
                2020-03-02
              </time>
            

            

            
          </span>

          
            <span class="post-category" >
            
              <span class="post-meta-divider">|</span>
            
              <span class="post-meta-item-icon">
                <i class="fa fa-folder-o"></i>
              </span>
              
                <span class="post-meta-item-text">分类于</span>
              
              
                <span itemprop="about" itemscope itemtype="http://schema.org/Thing">
                  <a href="/Liang34/categories/%E7%AE%97%E6%B3%95/" itemprop="url" rel="index">
                    <span itemprop="name">算法</span>
                  </a>
                </span>

                
                
              
            </span>
          

          
            
          

          
          

          

          

          

        </div>
      </header>
    

    
    
    
    <div class="post-body" itemprop="articleBody">

      
      

      
        
          
            <h1 id="选择排序（不稳定算法）"><a href="#选择排序（不稳定算法）" class="headerlink" title="选择排序（不稳定算法）"></a>选择排序（不稳定算法）</h1><h3 id="思想：选择排序，从头至尾扫描序列，找出最小的一个元素，和第一个元素交换，接着从剩下的元素中继续这种选择和交换方式，最终得到一个有序序列。"><a href="#思想：选择排序，从头至尾扫描序列，找出最小的一个元素，和第一个元素交换，接着从剩下的元素中继续这种选择和交换方式，最终得到一个有序序列。" class="headerlink" title="思想：选择排序，从头至尾扫描序列，找出最小的一个元素，和第一个元素交换，接着从剩下的元素中继续这种选择和交换方式，最终得到一个有序序列。"></a>思想：选择排序，从头至尾扫描序列，找出最小的一个元素，和第一个元素交换，接着从剩下的元素中继续这种选择和交换方式，最终得到一个有序序列。</h3><hr>
<h4 id="实例：-12-45-40-24-15-11-12-11-，初始数组内均为有序区"><a href="#实例：-12-45-40-24-15-11-12-11-，初始数组内均为有序区" class="headerlink" title="实例：[12,45,40,24,15,11,12,11]，初始数组内均为有序区"></a>实例：[12,45,40,24,15,11,12,11]，初始数组内均为有序区</h4><h4 id="第一趟遍历：-11-40-24-15-45-12-，花扩号内为无序区"><a href="#第一趟遍历：-11-40-24-15-45-12-，花扩号内为无序区" class="headerlink" title="第一趟遍历：[{11},40,24,15,45,12]，花扩号内为无序区"></a>第一趟遍历：[{11},40,24,15,45,12]，花扩号内为无序区</h4><h4 id="第二趟遍历：-11-12-24-15-45-40"><a href="#第二趟遍历：-11-12-24-15-45-40" class="headerlink" title="第二趟遍历：[{11,12},24,15,45,40]"></a>第二趟遍历：[{11,12},24,15,45,40]</h4><h4 id="第三趟遍历-11-12-15-24-45-40"><a href="#第三趟遍历-11-12-15-24-45-40" class="headerlink" title="第三趟遍历: [{11,12,15},24,45,40]"></a>第三趟遍历: [{11,12,15},24,45,40]</h4><h4 id="第四趟遍历-11-12-15-24-45-40"><a href="#第四趟遍历-11-12-15-24-45-40" class="headerlink" title="第四趟遍历: [{11,12,15,24},45,40]"></a>第四趟遍历: [{11,12,15,24},45,40]</h4><h4 id="第五趟遍历-11-12-15-24-40-45"><a href="#第五趟遍历-11-12-15-24-40-45" class="headerlink" title="第五趟遍历: [{11,12,15,24,40},45]"></a>第五趟遍历: [{11,12,15,24,40},45]</h4><hr>
<h4 id="算法分析：时间复杂度为O-n-2"><a href="#算法分析：时间复杂度为O-n-2" class="headerlink" title="算法分析：时间复杂度为O(n^2)"></a>算法分析：时间复杂度为O(n^2)</h4><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">selectOrder</span>(<span class="params">arr</span>)</span>&#123;</span><br><span class="line">    <span class="keyword">let</span> n=arr.length;</span><br><span class="line">    <span class="keyword">for</span>(<span class="keyword">let</span> i=<span class="number">0</span>;i&lt;n<span class="number">-1</span>;i++ )&#123;</span><br><span class="line">        <span class="keyword">let</span> index=i;</span><br><span class="line">        <span class="keyword">let</span> j;</span><br><span class="line">        <span class="comment">// 找出最小元素的下标</span></span><br><span class="line">        <span class="keyword">for</span>(j= i + <span class="number">1</span>;j&lt;n;j++)&#123;</span><br><span class="line">            <span class="keyword">if</span>(arr[index]&gt;arr[j])&#123;</span><br><span class="line">                index=j;</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">let</span> temp=arr[i];</span><br><span class="line">        arr[i]=arr[index];</span><br><span class="line">        arr[index]=temp;</span><br><span class="line">        <span class="built_in">console</span>.log(arr.toString());</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br><span class="line"><span class="keyword">let</span> arr=[<span class="number">45</span>,<span class="number">40</span>,<span class="number">24</span>,<span class="number">15</span>,<span class="number">11</span>,<span class="number">12</span>];</span><br><span class="line">selectOrder(arr)</span><br></pre></td></tr></table></figure>
          
        
      
    </div>
    
    
    

    

    

    

    <footer class="post-footer">
      

      

      

      
      
        <div class="post-eof"></div>
      
    </footer>
  </div>
  
  
  
  </article>


    
      

  

  
  
  

  <article class="post post-type-normal" itemscope itemtype="http://schema.org/Article">
  
  
  
  <div class="post-block">
    <link itemprop="mainEntityOfPage" href="https://liang34.github.io/Liang34/Liang34/2020/03/02/fastOrder/">

    <span hidden itemprop="author" itemscope itemtype="http://schema.org/Person">
      <meta itemprop="name" content="LiangJH">
      <meta itemprop="description" content="">
      <meta itemprop="image" content="/Liang34/images/avatar.jpg">
    </span>

    <span hidden itemprop="publisher" itemscope itemtype="http://schema.org/Organization">
      <meta itemprop="name" content="liang34">
    </span>

    
      <header class="post-header">

        
        
          <h1 class="post-title" itemprop="name headline">
                
                <a class="post-title-link" href="/Liang34/2020/03/02/fastOrder/" itemprop="url">fastOrder</a></h1>
        

        <div class="post-meta">
          <span class="post-time">
            
              <span class="post-meta-item-icon">
                <i class="fa fa-calendar-o"></i>
              </span>
              
                <span class="post-meta-item-text">发表于</span>
              
              <time title="创建于" itemprop="dateCreated datePublished" datetime="2020-03-02T17:33:16+08:00">
                2020-03-02
              </time>
            

            

            
          </span>

          
            <span class="post-category" >
            
              <span class="post-meta-divider">|</span>
            
              <span class="post-meta-item-icon">
                <i class="fa fa-folder-o"></i>
              </span>
              
                <span class="post-meta-item-text">分类于</span>
              
              
                <span itemprop="about" itemscope itemtype="http://schema.org/Thing">
                  <a href="/Liang34/categories/%E7%AE%97%E6%B3%95/" itemprop="url" rel="index">
                    <span itemprop="name">算法</span>
                  </a>
                </span>

                
                
              
            </span>
          

          
            
          

          
          

          

          

          

        </div>
      </header>
    

    
    
    
    <div class="post-body" itemprop="articleBody">

      
      

      
        
          
            <h1 id="快速排序"><a href="#快速排序" class="headerlink" title="快速排序"></a>快速排序</h1><h3 id="思想：用分而治之的思想，当数组中仅为一个元素是就停止递归，否则将从数组中取出一个基准值-任意-，将比其大的放右边，小的放左边，再在子数组中一直递归直到达到基线条件为止"><a href="#思想：用分而治之的思想，当数组中仅为一个元素是就停止递归，否则将从数组中取出一个基准值-任意-，将比其大的放右边，小的放左边，再在子数组中一直递归直到达到基线条件为止" class="headerlink" title="思想：用分而治之的思想，当数组中仅为一个元素是就停止递归，否则将从数组中取出一个基准值(任意)，将比其大的放右边，小的放左边，再在子数组中一直递归直到达到基线条件为止"></a>思想：用分而治之的思想，当数组中仅为一个元素是就停止递归，否则将从数组中取出一个基准值(任意)，将比其大的放右边，小的放左边，再在子数组中一直递归直到达到基线条件为止</h3><hr>
<pre><code>案例：[2,6,1,4,8]，先取基准值2
第一趟：{1},2,{6,4,8} 左边花括号为less，右边为more,less等于一直接返回，more中去基准值4
第二趟：1,2,{4},6,{8}结束</code></pre><hr>
<h3 id="算法分析：时间复杂度是O-n-log2-n-，最坏情形性能为O-n-2"><a href="#算法分析：时间复杂度是O-n-log2-n-，最坏情形性能为O-n-2" class="headerlink" title="算法分析：时间复杂度是O(n*log2^n)，最坏情形性能为O(n^2)"></a>算法分析：时间复杂度是O(n*log2^n)，最坏情形性能为O(n^2)</h3><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">fastOrder</span>(<span class="params">arr</span>)</span>&#123;</span><br><span class="line">    <span class="keyword">if</span>(arr.length &lt; <span class="number">2</span>) &#123;<span class="comment">//基线条件</span></span><br><span class="line">        <span class="keyword">return</span> arr;</span><br><span class="line">    &#125;<span class="keyword">else</span>&#123;             <span class="comment">// 递归条件</span></span><br><span class="line">        <span class="keyword">let</span> stand=arr[<span class="number">0</span>];</span><br><span class="line">        arr=arr.splice(<span class="number">1</span>,arr.length) <span class="comment">//去除基准数，splice返回值为数组。</span></span><br><span class="line">        <span class="keyword">let</span> more=[];</span><br><span class="line">        <span class="keyword">let</span> less=[];</span><br><span class="line">        arr.forEach(<span class="function"><span class="params">element</span> =&gt;</span> &#123;</span><br><span class="line">            <span class="keyword">if</span>(element&gt;stand)&#123;</span><br><span class="line">                more.push(element);<span class="comment">//大于基准值的数组</span></span><br><span class="line">            &#125;<span class="keyword">else</span>&#123;</span><br><span class="line">                less.push(element);<span class="comment">//小于基准值的数组</span></span><br><span class="line">            &#125;</span><br><span class="line">        &#125;);</span><br><span class="line">        <span class="keyword">return</span> fastOrder(less).concat([stand],fastOrder(more));<span class="comment">//加回基准数</span></span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br><span class="line"><span class="keyword">let</span> arr=[<span class="number">2</span>,<span class="number">6</span>,<span class="number">1</span>,<span class="number">4</span>,<span class="number">8</span>];</span><br><span class="line"><span class="keyword">let</span> arr1=fastOrder(arr);</span><br><span class="line"><span class="built_in">console</span>.log(arr1)<span class="comment">//[1, 2, 4, 6, 8]</span></span><br></pre></td></tr></table></figure>
          
        
      
    </div>
    
    
    

    

    

    

    <footer class="post-footer">
      

      

      

      
      
        <div class="post-eof"></div>
      
    </footer>
  </div>
  
  
  
  </article>


    
      

  

  
  
  

  <article class="post post-type-normal" itemscope itemtype="http://schema.org/Article">
  
  
  
  <div class="post-block">
    <link itemprop="mainEntityOfPage" href="https://liang34.github.io/Liang34/Liang34/2020/02/01/%E5%8E%9F%E5%9E%8B/">

    <span hidden itemprop="author" itemscope itemtype="http://schema.org/Person">
      <meta itemprop="name" content="LiangJH">
      <meta itemprop="description" content="">
      <meta itemprop="image" content="/Liang34/images/avatar.jpg">
    </span>

    <span hidden itemprop="publisher" itemscope itemtype="http://schema.org/Organization">
      <meta itemprop="name" content="liang34">
    </span>

    
      <header class="post-header">

        
        
          <h1 class="post-title" itemprop="name headline">
                
                <a class="post-title-link" href="/Liang34/2020/02/01/%E5%8E%9F%E5%9E%8B/" itemprop="url">hello</a></h1>
        

        <div class="post-meta">
          <span class="post-time">
            
              <span class="post-meta-item-icon">
                <i class="fa fa-calendar-o"></i>
              </span>
              
                <span class="post-meta-item-text">发表于</span>
              
              <time title="创建于" itemprop="dateCreated datePublished" datetime="2020-02-01T22:28:19+08:00">
                2020-02-01
              </time>
            

            

            
          </span>

          

          
            
          

          
          

          

          

          

        </div>
      </header>
    

    
    
    
    <div class="post-body" itemprop="articleBody">

      
      

      
        
          
            <h1 id="关于js中的原型-prototype）"><a href="#关于js中的原型-prototype）" class="headerlink" title="关于js中的原型(prototype）"></a>关于js中的原型(prototype）</h1><h2 id="01原型"><a href="#01原型" class="headerlink" title="01原型"></a>01原型</h2><ol>
<li><p>函数的prototype属性</p>
<ul>
<li>每个函数都有一个prototype属性, 它默认指向一个Object空对象(即称为: 原型对象)</li>
<li>原型对象中有一个属性constructor, 它指向函数对象</li>
</ul>
</li>
<li><p>给原型对象添加属性(一般都是方法)</p>
<ul>
<li><p>作用: 函数的所有实例对象自动拥有原型中的属性(方法)</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br></pre></td><td class="code"><pre><span class="line">&lt;body&gt;</span><br><span class="line">&lt;script type&#x3D;&quot;text&#x2F;javascript&quot;&gt;</span><br><span class="line">&#x2F;&#x2F; 每个函数都有一个prototype属性, 它默认指向一个对象(即称为: 原型对象)</span><br><span class="line">console.log(Date.prototype, typeof Date.prototype)&#x2F;&#x2F;Object &quot;object&quot;</span><br><span class="line">function fn() &#123;</span><br><span class="line"></span><br><span class="line">&#125;</span><br><span class="line">console.log(fn.prototype, typeof fn.prototype)&#x2F;&#x2F;Object &quot;object&quot;</span><br><span class="line"></span><br><span class="line">&#x2F;&#x2F; 原型对象中有一个属性constructor, 它指向函数对象</span><br><span class="line">console.log(Date.prototype.constructor&#x3D;&#x3D;&#x3D;Date)&#x2F;&#x2F;true</span><br><span class="line">console.log(fn.prototype.constructor&#x3D;&#x3D;&#x3D;fn)&#x2F;&#x2F;true</span><br><span class="line"></span><br><span class="line">&#x2F;&#x2F; 2. 给原型对象添加属性(一般都是方法)</span><br><span class="line">function F() &#123;</span><br><span class="line"></span><br><span class="line">&#125;</span><br><span class="line">F.prototype.age &#x3D; 12 &#x2F;&#x2F;添加属性</span><br><span class="line">F.prototype.setAge &#x3D; function (age) &#123; &#x2F;&#x2F; 添加方法</span><br><span class="line">    this.age &#x3D; age</span><br><span class="line">&#125;</span><br><span class="line">&#x2F;&#x2F; 创建函数的实例对象</span><br><span class="line">var f &#x3D; new F()</span><br><span class="line">console.log(f.age)</span><br><span class="line">f.setAge(23)</span><br><span class="line">console.log(f.age)</span><br><span class="line"></span><br><span class="line">&lt;&#x2F;script&gt;</span><br><span class="line">&lt;&#x2F;body&gt;</span><br></pre></td></tr></table></figure>
<h2 id="02-显式原型与隐式原型"><a href="#02-显式原型与隐式原型" class="headerlink" title="02_显式原型与隐式原型"></a>02_显式原型与隐式原型</h2></li>
</ul>
</li>
<li><p>每个函数function都有一个prototype，即显式原型</p>
</li>
<li><p>每个实例对象都有一个<strong>proto</strong>，可称为隐式原型</p>
</li>
<li><p>对象的隐式原型的值为其对应构造函数的显式原型的值</p>
</li>
<li><p>内存结构</p>
</li>
<li><p>总结:</p>
<ul>
<li>函数的prototype属性: 在定义函数时自动添加的, 默认值是一个空Object对象</li>
<li>对象的<strong>proto</strong>属性: 创建对象时自动添加的, 默认值为构造函数的prototype属性值</li>
<li>程序员能直接操作显式原型, 但不能直接操作隐式原型(ES6之前)<h2 id="03原型链"><a href="#03原型链" class="headerlink" title="03原型链"></a>03原型链</h2><h3 id="1-原型链"><a href="#1-原型链" class="headerlink" title="1. 原型链"></a>1. 原型链</h3><ul>
<li>访问一个对象的属性时，</li>
<li>先在自身属性中查找，找到返回</li>
<li>如果没有, 再沿着<strong>proto</strong>这条链向上查找, 找到返回</li>
<li>如果最终没找到, 返回undefined</li>
<li>别名: 隐式原型链</li>
<li>作用: 查找对象的属性(方法)<h3 id="2-原型链-属性问题"><a href="#2-原型链-属性问题" class="headerlink" title="2.原型链_属性问题"></a>2.原型链_属性问题</h3></li>
<li>读取对象的属性值时: 会自动到原型链中查找</li>
<li>设置对象的属性值时: 不会查找原型链, 如果当前对象中没有此属性, 直接添加此属性并设置其值</li>
<li>方法一般定义在原型中, 属性一般通过构造函数定义在对象本身上<h3 id="3-instanceof"><a href="#3-instanceof" class="headerlink" title="3.instanceof"></a>3.instanceof</h3></li>
<li>instanceof是如何判断的?</li>
<li>表达式: A (实例对象）instanceof B（构造函数对象）</li>
<li>如果B函数的显式原型对象在A对象的原型链上, 返回true, 否则返回false<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br></pre></td><td class="code"><pre><span class="line">&lt;script type&#x3D;&quot;text&#x2F;javascript&quot;&gt;</span><br><span class="line">  &#x2F;&#x2F;案例1</span><br><span class="line">  function Foo() &#123;  &#125;</span><br><span class="line">  var f1 &#x3D; new Foo();</span><br><span class="line">  console.log(f1 instanceof Foo);&#x2F;&#x2F;true</span><br><span class="line">  console.log(f1 instanceof Object);&#x2F;&#x2F;true</span><br><span class="line"></span><br><span class="line">  &#x2F;&#x2F;案例2</span><br><span class="line">  console.log(Object instanceof Function)&#x2F;&#x2F;true</span><br><span class="line">  console.log(Object instanceof Object)&#x2F;&#x2F;true</span><br><span class="line">    &#x2F;&#x2F;* object作为实例对象是其隐式原型指向function.prototype,而</span><br><span class="line">    &#x2F;&#x2F;* function.prototype的隐式原型指向Object.prototype</span><br><span class="line">    &#x2F;&#x2F;* 作为实例对象时其显示原型指向Object.prototype</span><br><span class="line">  console.log(Function instanceof Object)&#x2F;&#x2F;true</span><br><span class="line">  console.log(Function instanceof Function)&#x2F;&#x2F;true</span><br><span class="line">  function Foo() &#123;&#125;</span><br><span class="line">  console.log(Object instanceof  Foo);&#x2F;&#x2F;false</span><br><span class="line">&lt;&#x2F;script&gt;</span><br></pre></td></tr></table></figure>
<h3 id="4-面试题"><a href="#4-面试题" class="headerlink" title="4.面试题"></a>4.面试题</h3><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br></pre></td><td class="code"><pre><span class="line">&lt;script type&#x3D;&quot;text&#x2F;javascript&quot;&gt;</span><br><span class="line">  &#x2F;*</span><br><span class="line">  测试题1</span><br><span class="line">   *&#x2F;</span><br><span class="line">  var A &#x3D; function() &#123;</span><br><span class="line"></span><br><span class="line">  &#125;</span><br><span class="line">  A.prototype.n &#x3D; 1</span><br><span class="line"></span><br><span class="line">  var b &#x3D; new A()</span><br><span class="line"></span><br><span class="line">  A.prototype &#x3D; &#123;</span><br><span class="line">    n: 2,</span><br><span class="line">    m: 3</span><br><span class="line">  &#125;</span><br><span class="line"></span><br><span class="line">  var c &#x3D; new A()</span><br><span class="line">  console.log(b.n, b.m, c.n, c.m)&#x2F;&#x2F;1，undefined，2，3</span><br><span class="line"></span><br><span class="line"></span><br><span class="line">  &#x2F;*</span><br><span class="line">   测试题2</span><br><span class="line">   *&#x2F;</span><br><span class="line">  var F &#x3D; function()&#123;&#125;;</span><br><span class="line">  Object.prototype.a &#x3D; function()&#123;</span><br><span class="line">    console.log(&#39;a()&#39;)</span><br><span class="line">  &#125;;</span><br><span class="line">  Function.prototype.b &#x3D; function()&#123;</span><br><span class="line">    console.log(&#39;b()&#39;)</span><br><span class="line">  &#125;;</span><br><span class="line">  var f &#x3D; new F();</span><br><span class="line">  f.a()</span><br><span class="line">  &#x2F;&#x2F;f.b()&#x2F;&#x2F;报错</span><br><span class="line">  F.a()</span><br><span class="line">  F.b()</span><br><span class="line"></span><br><span class="line">&lt;&#x2F;script&gt;</span><br></pre></td></tr></table></figure></li>
</ul>
</li>
</ul>
</li>
</ol>

          
        
      
    </div>
    
    
    

    

    

    

    <footer class="post-footer">
      

      

      

      
      
        <div class="post-eof"></div>
      
    </footer>
  </div>
  
  
  
  </article>


    
  </section>

  


          </div>
          


          

        </div>
        
          
  
  <div class="sidebar-toggle">
    <div class="sidebar-toggle-line-wrap">
      <span class="sidebar-toggle-line sidebar-toggle-line-first"></span>
      <span class="sidebar-toggle-line sidebar-toggle-line-middle"></span>
      <span class="sidebar-toggle-line sidebar-toggle-line-last"></span>
    </div>
  </div>	
  <aside id="sidebar" class="sidebar">
    
    <div class="sidebar-inner">

      

      

      <section class="site-overview-wrap sidebar-panel sidebar-panel-active">
        <div class="site-overview">
          <div class="site-author motion-element" itemprop="author" itemscope itemtype="http://schema.org/Person">
            
              <img class="site-author-image" itemprop="image"
                src="/Liang34/images/avatar.jpg"
                alt="LiangJH" />
            
              <p class="site-author-name" itemprop="name">LiangJH</p>
              <p class="site-description motion-element" itemprop="description">前端,java</p>
          </div>

          <nav class="site-state motion-element">

            
              <div class="site-state-item site-state-posts">
              
                <a href="/Liang34/archives/%7C%7C%20archive">
              
                  <span class="site-state-item-count">7</span>
                  <span class="site-state-item-name">日志</span>
                </a>
              </div>
            

            
              
              
              <div class="site-state-item site-state-categories">
                
                  <span class="site-state-item-count">3</span>
                  <span class="site-state-item-name">分类</span>
                
              </div>
            

            
              
              
              <div class="site-state-item site-state-tags">
                
                  <span class="site-state-item-count">1</span>
                  <span class="site-state-item-name">标签</span>
                
              </div>
            

          </nav>

          

          

          
          

          
          

          

        </div>
      </section>

      

      

    </div>
  </aside>


        
      </div>
    </main>

    <footer id="footer" class="footer">
      <div class="footer-inner">
        <div class="copyright">&copy; <span itemprop="copyrightYear">2020</span>
  <span class="with-love">
    <i class="fa fa-user"></i>
  </span>
  <span class="author" itemprop="copyrightHolder">LiangJH</span>

  
</div>


  <div class="powered-by">由 <a class="theme-link" target="_blank" href="https://hexo.io">Hexo</a> 强力驱动</div>



  <span class="post-meta-divider">|</span>



  <div class="theme-info">主题 &mdash; <a class="theme-link" target="_blank" href="https://github.com/iissnan/hexo-theme-next">NexT.Pisces</a> v5.1.4</div>




        







        
      </div>
    </footer>

    
      <div class="back-to-top">
        <i class="fa fa-arrow-up"></i>
        
      </div>
    

    

  </div>

  

<script type="text/javascript">
  if (Object.prototype.toString.call(window.Promise) !== '[object Function]') {
    window.Promise = null;
  }
</script>









  












  
  
    <script type="text/javascript" src="/Liang34/lib/jquery/index.js?v=2.1.3"></script>
  

  
  
    <script type="text/javascript" src="/Liang34/lib/fastclick/lib/fastclick.min.js?v=1.0.6"></script>
  

  
  
    <script type="text/javascript" src="/Liang34/lib/jquery_lazyload/jquery.lazyload.js?v=1.9.7"></script>
  

  
  
    <script type="text/javascript" src="/Liang34/lib/velocity/velocity.min.js?v=1.2.1"></script>
  

  
  
    <script type="text/javascript" src="/Liang34/lib/velocity/velocity.ui.min.js?v=1.2.1"></script>
  

  
  
    <script type="text/javascript" src="/Liang34/lib/fancybox/source/jquery.fancybox.pack.js?v=2.1.5"></script>
  


  


  <script type="text/javascript" src="/Liang34/js/src/utils.js?v=5.1.4"></script>

  <script type="text/javascript" src="/Liang34/js/src/motion.js?v=5.1.4"></script>



  
  


  <script type="text/javascript" src="/Liang34/js/src/affix.js?v=5.1.4"></script>

  <script type="text/javascript" src="/Liang34/js/src/schemes/pisces.js?v=5.1.4"></script>



  

  


  <script type="text/javascript" src="/Liang34/js/src/bootstrap.js?v=5.1.4"></script>



  


  




	





  





  












  





  

  

  

  
  

  

  

  

<script src="/Liang34/live2dw/lib/L2Dwidget.min.js?094cbace49a39548bed64abff5988b05"></script><script>L2Dwidget.init({"pluginRootPath":"live2dw/","pluginJsPath":"lib/","pluginModelPath":"assets/","tagMode":false,"debug":false,"model":{"jsonPath":"/Liang34/live2dw/assets/hibiki.model.json"},"display":{"position":"right","width":145,"height":315},"mobile":{"show":true,"scale":0.5},"react":{"opacityDefault":0.7,"opacityOnHover":0.8},"log":false});</script></body>
</html>
